package com.mathassistant.client.presenter;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.mathassistant.client.event.topic.TopicListUpdateEvent;
import com.mathassistant.client.helper.RPCCall;
import com.mathassistant.client.service.TopicServiceAsync;
import com.mathassistant.shared.TopicDTO;

public class TopicEditPresenter implements Presenter {

	public interface Display {
		HasClickHandlers getAddButton();

		HasClickHandlers getCancelButton();

		HasValue<String> getTopicContentTextBox();

		Widget asWidget();

		void hideDialog();

		void showDialog();

		void setContentAndShow(String content);
	}

	private final Display display;
	private final SimpleEventBus eventBus;
	private final TopicServiceAsync rpcService;
	
	private TopicDTO topic;
	private String area;
	private String contentType;
	
	public Display getDisplay() {
		return display;
	}

	public TopicEditPresenter(TopicDTO topic, TopicServiceAsync rpcService,
			SimpleEventBus eventBus, Display view) {
		this.topic = topic;
		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = view;
		bind();
	}

	public TopicEditPresenter(TopicDTO topic, String area, String contentType, 
			TopicServiceAsync rpcService, SimpleEventBus eventBus, Display view) {
		this.topic = topic;
		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = view;
		this.area = area;
		this.contentType = contentType;
		bind();
	}
	
	private void bind() {
		// TODO Auto-generated method stub
		display.getCancelButton().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				// TODO Auto-generated method stub
				display.hideDialog();
			}
		});

		display.getAddButton().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				// TODO Auto-generated method stub
				doAddButton();
				display.hideDialog();
			}
		});
	}

	protected void doAddButton() {
		// TODO Auto-generated method stub
		if (topic == null) {
			topic = new TopicDTO();
			topic.setContent(display.getTopicContentTextBox().getValue());
			topic.setArea(area);
			topic.setContentType(contentType);
			
			new RPCCall<Void>() {

				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					Window.alert("Error save topic: " + caught.getMessage());
				}

				@Override
				public void onSuccess(Void result) {
					// TODO Auto-generated method stub
					eventBus.fireEvent(new TopicListUpdateEvent(area,contentType));
					display.hideDialog();
				}

				@Override
				protected void callService(AsyncCallback<Void> cb) {
					// TODO Auto-generated method stub
					rpcService.createTopic(topic, cb);
				}
			}.retry(3);
		} else {
			topic.setContent(display.getTopicContentTextBox().getValue());
			
			new RPCCall<Void>() {

				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					Window.alert("Error save topic: " + caught.getMessage());
				}

				@Override
				public void onSuccess(Void result) {
					// TODO Auto-generated method stub
					eventBus.fireEvent(new TopicListUpdateEvent(topic.getArea(),topic.getContentType()));
					display.hideDialog();
				}

				@Override
				protected void callService(AsyncCallback<Void> cb) {
					// TODO Auto-generated method stub
					rpcService.updateTopic(topic, cb);
				}
			}.retry(3);

		}
	}

	@Override
	public void go(HasWidgets container) {
		// TODO Auto-generated method stub

	}

	@Override
	public void go() {
		// TODO Auto-generated method stub

	}

	public void setArea(String area) {
		this.area = area;
	}

	public String getArea() {
		return area;
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public String getContentType() {
		return contentType;
	}

}
